#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys, signal, commands, hashlib, os, platform, re, tempfile, time, os, os.path, string, subprocess, codecs, locale, multiprocessing, datetime

import socket


def generate_git_info_for_backend():
    G_CI_SERVER_HOST_IPV4 = get_host_ipv4()
    G_CI_SERVER_HOST_NAME = get_host_name()
    G_GIT_INFO_BRANCH_NAME = get_git_info_branch_name()
    G_GIT_INFO_LAST_UPDATE_TIME_STD_FMT = get_git_info_last_update_time_std_fmt()
    G_GIT_INFO_LAST_UPDATE_TIME_INT_FMT = get_git_info_last_update_time_int_fmt()
    G_GIT_INFO_INT_VERSION = get_git_info_int_version()
    G_GIT_INFO_MD5_VERSION = get_git_info_md5_version()
    G_GIT_LAST_UPDATE_MESSAGE = get_git_last_update_message()
    G_GIT_LAST_TAG_NAME = get_git_last_tag_name()
    G_GIT_CURR_TAG_NAME = get_git_curr_tag_name()

    G_BUILD_TIME = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    version_file = 'backend/base/src/main/resources/__v__.properties'
    version_info_array = ['',
                          '# This file was auto-generated by build script, DO NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT modify it !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!',
                          '',
                          '# 该文件由构建脚本自动生成, 切切切切切切切切切切切切勿勿勿勿勿勿勿勿勿勿勿勿勿勿勿勿勿改动之',
                          '',
                          '',
                          'v.G_CI_SERVER_HOST_IPV4 = %s' % (G_CI_SERVER_HOST_IPV4),
                          'v.G_CI_SERVER_HOST_NAME = %s' % (G_CI_SERVER_HOST_NAME),
                          '',
                          '',
                          'v.G_GIT_INFO_BRANCH_NAME = %s' % (G_GIT_INFO_BRANCH_NAME),
                          'v.G_GIT_LAST_TAG_NAME = %s' % (G_GIT_LAST_TAG_NAME),
                          'v.G_GIT_CURR_TAG_NAME = %s' % (G_GIT_CURR_TAG_NAME),
                          'v.G_GIT_INFO_LAST_UPDATE_TIME_STD_FMT = %s' % (G_GIT_INFO_LAST_UPDATE_TIME_STD_FMT),
                          'v.G_GIT_INFO_LAST_UPDATE_TIME_INT_FMT = %s' % (G_GIT_INFO_LAST_UPDATE_TIME_INT_FMT),
                          'v.G_GIT_INFO_INT_VERSION = %s' % (G_GIT_INFO_INT_VERSION),
                          'v.G_GIT_INFO_MD5_VERSION = %s' % (G_GIT_INFO_MD5_VERSION),
                          'v.G_GIT_LAST_UPDATE_MESSAGE = %s' % (G_GIT_LAST_UPDATE_MESSAGE),
                          'v.G_BUILD_TIME = %s' % (G_BUILD_TIME),
                          'v.G_TIP = %s' % ('inject_by_build_script'),
                          '',
                          '',
                          '']
    #
    if os.path.exists(version_file):
        os.remove(version_file)
    #
    with open(version_file, 'w') as f:
        for line in version_info_array:
            f.writelines('%s%s' % ('\n', line))


def kill_ngx_process_by():
    """

    :return:
    """
    ipv4 = get_host_ipv4()

    cmd = "ps aux | grep nginx | grep 'nginx.conf' | awk '{ print $2 }'"
    status, output = commands.getstatusoutput(cmd)
    if output is not None and len(output) > 0:
        i = 0
        arr = output.split('\n')
        for pid in arr:
            i += 1
            os.system("echo 'pid={}---------------------------------------------------------index={}'".format(pid, i))
            os.system("echo 'nginx is already running with (pid= %s), i will kill it soon--->%s'" % (pid, ipv4))
            cmd = 'kill %s' % (pid)
            os.system(cmd)
            os.system("echo 'nginx which pid is %s be killed--->%s'" % (pid, ipv4))
            os.system("echo ''")
    else:
        os.system("echo ''")
        os.system("echo 'there is no nginx running--->%s'" % (ipv4))
        os.system("echo ''")


def kill_apache_tomcat_process_by(p_apache_tomcat_dir_name=None):
    """

    :param p_apache_tomcat_dir_name:
    :return:
    """
    ipv4 = get_host_ipv4()

    cmd = "ps aux | grep %s | grep org.apache.catalina.startup.Bootstrap | grep -v grep | awk '{ print $2 }'" % (p_apache_tomcat_dir_name)
    # os.system(cmd)
    status, output = commands.getstatusoutput(cmd)

    if output is not None and len(output) > 0:
        try:
            pid = output
            os.system("echo ''")
            os.system("echo ''")
            os.system("echo ''")
            os.system("echo 'tomcat is already running with (pid= %s), i will kill it soon--->%s'" % (pid, ipv4))
            cmd = 'kill %s' % (pid)
            os.system(cmd)
            os.system("echo '%s which pid is %s be killed--->%s'" % (p_apache_tomcat_dir_name, pid, ipv4))
            os.system("echo ''")
            os.system("echo ''")
        except Exception as e:
            os.system("echo '%s'" % (str(e)))
    else:
        os.system("echo ''")
        os.system("echo ''")
        os.system("echo ''")
        os.system("echo 'there is no %s running--->%s'" % (p_apache_tomcat_dir_name, ipv4))
        os.system("echo ''")
        os.system("echo ''")
        os.system("echo ''")


def kill_processes_by_port(p_port=None):
    '''

    :param p_port:
    :return:
    '''
    pids = get_pid_array_of(p_port=p_port)
    for pid in pids:
        # command = 'sudo kill -9 %s' % (pid)
        # os.system(command)
        try:
            os.kill(pid, signal.SIGKILL)
            print('pid %s be killed' % (pid))
        except Exception, e:
            print('no pid %s' % (pid))


def get_pid_array_of(p_port=None):
    '''

    :param p_port:
    :return: Return an array of pid
    '''
    arr = []
    try:
        command = "sudo lsof -i :%s | awk '{print $2}'" % p_port
        pids = subprocess.check_output(command, shell=True)
        pids = pids.strip()
        if pids:
            pids = re.sub(' +', ' ', pids)
            arr = pids.split('\n')
        else:
            arr = []
    except Exception, e:
        arr = []
    return arr


def get_host_ipv4():
    """
    :return: ipv4
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ipv4 = s.getsockname()[0]
    except Exception, e:
        ipv4 = '0.0.0.0'
    finally:
        s.close()

    return ipv4


def get_system_encoding():
    """
    The encoding of the default system locale but falls back to the given
    fallback encoding if the encoding is unsupported by python or could
    not be determined. See tickets #10335 and #5846
    """
    try:
        encoding = locale.getdefaultlocale()[1] or 'ascii'
        codecs.lookup(encoding)
    except Exception:
        encoding = 'ascii'
    return encoding


def get_os_info():
    dic = dict()
    # Returns the machine type, e.g. 'i386'
    dic['os_machine'] = platform.machine()
    # Returns the computer's network name
    dic['os_node'] = platform.node()
    # Returns a single string identifying the underlying platform
    dic['os_platform'] = platform.platform(aliased=0, terse=0)
    # # Returns the (true) processor name
    dic['os_processor'] = platform.processor()
    # Returns the system's release, e.g. '2.2.0' or 'NT'
    dic['os_release'] = platform.release()
    # Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'
    dic['os_system'] = platform.system()
    # Fairly portable uname interface. Returns a tuple of strings (system,node,release,version,machine,processor) identifying the underlying platform.
    dic['os_uname'] = platform.uname()
    # Get additional version information from the Windows Registry and return a tuple (version,csd,ptype) referring to version number, CSD level and OS type (multi/single processor).
    dic['os_win32_ver'] = platform.win32_ver(release='', version='', csd='', ptype='')
    dic['os_system_encoding'] = get_system_encoding()
    dic['os_cpu_count'] = multiprocessing.cpu_count()

    # 返回当前系统所使用的默认字符编码
    dic['os_defaultencoding'] = sys.getdefaultencoding()
    # 返回用于转换Unicode文件名至系统文件名所使用的编码
    dic['os_filesystemencoding'] = sys.getfilesystemencoding()
    # 获取默认的区域设置并返回元祖(语言, 编码)
    # 返回用户设定的文本数据编码
    # 文档提到this function only returns a guess
    # locale.getdefaultlocale()
    dic['os_defaultlocale'] = os.environ.get('LANG')
    return dic


def memory_stat():
    mem = dict()
    f = open("/proc/meminfo")
    lines = f.readlines()
    f.close()
    for line in lines:
        if len(line) < 2: continue
        name = line.split(':')[0]
        var = line.split(':')[1].split()[0]
        mem[name] = long(var) * 1024.0
    mem['MemUsed'] = mem['MemTotal'] - mem['MemFree'] - mem['Buffers'] - mem['Cached']
    return mem


def cpu_stat():
    cpu = []
    cpuinfo = dict()
    f = open("/proc/cpuinfo")
    lines = f.readlines()
    f.close()
    for line in lines:
        if line == '\n':
            cpu.append(cpuinfo)
            cpuinfo = {}
        if len(line) < 2: continue
        name = line.split(':')[0].rstrip()
        var = line.split(':')[1]
        cpuinfo[name] = var
    return cpu


def uptime_stat():
    uptime = dict()
    f = open("/proc/uptime")
    con = f.read().split()
    f.close()
    all_sec = float(con[0])
    MINUTE, HOUR, DAY = 60, 3600, 86400
    uptime['day'] = int(all_sec / DAY)
    uptime['hour'] = int((all_sec % DAY) / HOUR)
    uptime['minute'] = int((all_sec % HOUR) / MINUTE)
    uptime['second'] = int(all_sec % MINUTE)
    uptime['Free rate'] = float(con[1]) / float(con[0])
    return uptime


def disk_stat():
    hd = dict()
    disk = os.statvfs("/")
    hd['available'] = disk.f_bsize * disk.f_bavail / (1024 * 1024 * 1024 * 1024)
    hd['capacity'] = disk.f_bsize * disk.f_blocks / (1024 * 1024 * 1024 * 1024)
    hd['used'] = disk.f_bsize * disk.f_bfree / (1024 * 1024 * 1024 * 1024)
    return hd


def net_stat():
    net = []
    f = open("/proc/net/dev")
    lines = f.readlines()
    f.close()
    for line in lines[2:]:
        con = line.split()
        """
        intf = {}
        intf['interface'] = con[0].lstrip(":")
        intf['ReceiveBytes'] = int(con[1])
        intf['ReceivePackets'] = int(con[2])
        intf['ReceiveErrs'] = int(con[3])
        intf['ReceiveDrop'] = int(con[4])
        intf['ReceiveFifo'] = int(con[5])
        intf['ReceiveFrames'] = int(con[6])
        intf['ReceiveCompressed'] = int(con[7])
        intf['ReceiveMulticast'] = int(con[8])
        intf['TransmitBytes'] = int(con[9])
        intf['TransmitPackets'] = int(con[10])
        intf['TransmitErrs'] = int(con[11])
        intf['TransmitDrop'] = int(con[12])
        intf['TransmitFifo'] = int(con[13])
        intf['TransmitFrames'] = int(con[14])
        intf['TransmitCompressed'] = int(con[15])
        intf['TransmitMulticast'] = int(con[16])
        """
        intf = dict(
            zip(
                ('interface', 'ReceiveBytes', 'ReceivePackets',
                 'ReceiveErrs', 'ReceiveDrop', 'ReceiveFifo',
                 'ReceiveFrames', 'ReceiveCompressed', 'ReceiveMulticast',
                 'TransmitBytes', 'TransmitPackets', 'TransmitErrs',
                 'TransmitDrop', 'TransmitFifo', 'TransmitFrames',
                 'TransmitCompressed', 'TransmitMulticast'),
                (con[0].rstrip(":"), int(con[1]), int(con[2]),
                 int(con[3]), int(con[4]), int(con[5]),
                 int(con[6]), int(con[7]), int(con[8]),
                 int(con[9]), int(con[10]), int(con[11]),
                 int(con[12]), int(con[13]), int(con[14]),
                 int(con[15]), int(con[16]),)
            )
        )

        net.append(intf)
    return net


def get_host_name():
    """get host name

    :return: git infoascii
    :rtype: dict

    Usage::
    """
    v = 'unknown'
    from os import popen
    try:
        v = str(popen('hostname').read()).replace('\n', '')
    except Exception, e:
        v = 'unknown'
    return v


def get_git_info():
    """get version dict

    :return: version info
    :rtype: dict

    Usage::
    """
    d = dict()
    try:
        status, output = commands.getstatusoutput('git config log.date iso')

        if is_windows() is False:
            # status, output = commands.getstatusoutput('git show --summary')
            # g_git_last_update_time_std_fmt = output.split('\n')[2]
            # if g_git_last_update_time_std_fmt.find('Date:') < 0:
            #     g_git_last_update_time_std_fmt = output.split('\n')[3]
            # g_git_last_update_time_std_fmt = g_git_last_update_time_std_fmt.replace('Date:', '').replace('+0800', '').strip()
            # time_array = time.strptime(g_git_last_update_time_std_fmt, "%Y-%m-%d %H:%M:%S")
            # # standard format
            # g_git_last_update_time_std_fmt = time.strftime("%Y-%m-%d %H:%M:%S", time_array)
            # # int format
            # g_git_last_update_time_int_fmt = time.strftime("%Y%m%d%H%M%S", time_array)
            status, output = commands.getstatusoutput("git log --pretty=format:'%ad' --max-count=1")
            g_git_last_update_time_std_fmt = output.replace('+0800', '').strip()
            #
            time_array = time.strptime(g_git_last_update_time_std_fmt, "%Y-%m-%d %H:%M:%S")
            g_git_last_update_time_int_fmt = time.strftime("%Y%m%d%H%M%S", time_array)
        else:
            status, output = commands.getstatusoutput("git log --pretty=format:'%ad' --date=format:'%Y-%m-%d %H:%M:%S' --max-count=1")
            g_git_last_update_time_std_fmt = output
            #
            status, output = commands.getstatusoutput("git log --pretty=format:'%ad' --date=format:'%Y%m%d%H%M%S' --max-count=1")
            g_git_last_update_time_int_fmt = output

        # git log --pretty=format:'%ad' --date=format:'%Y-%m-%d %H:%M:%S' --max-count=1

        #
        status, output = commands.getstatusoutput('git log --since="Oct 27 9:16:10 2015 +0800"  --pretty=oneline | wc -l')
        g_git_int_version = output.strip()

        #
        status, output = commands.getstatusoutput('git log --pretty=format:"%H" -1')
        g_git_md5_version = output.strip()

        #
        cmd = "git branch  --no-color  | grep -E '^\*' | sed 's/\*[^a-z]*//g'"
        status, output = commands.getstatusoutput(cmd)
        g_git_branch_name = output.replace('detached at ', '').replace('detached from ', '').replace(')', '')

        status, output = commands.getstatusoutput("git show -s --format=%B | tr -s '\n'")
        g_git_last_update_message = output

        status, output = commands.getstatusoutput('git describe --tags $(git rev-list --tags --max-count=1)')
        g_git_last_tag_name = output

        #
        try:
            status, output = commands.getstatusoutput('git rev-list --tags')
            arr = output.split('\n')
            max_count = arr.index(g_git_md5_version) + 1
            # max_count = lastindex(arr, g_git_md5_version)
            status, output = commands.getstatusoutput('git describe --tags $(git rev-list --tags --max-count={})'.format(max_count))
            arr = output.split('\n')
            g_git_curr_tag_name = arr[-1]
        except Exception, e:
            g_git_curr_tag_name = 'unknown'
    except Exception, e:
        print('Exception=', e)
        g_git_branch_name = 'unknown'
        g_git_last_update_time_std_fmt = 'unknown'
        g_git_last_update_time_int_fmt = 'unknown'
        g_git_int_version = -1
        g_git_md5_version = 'unknown_version'
        g_git_last_update_message = 'unknown'
        g_git_last_tag_name = 'unknown'
        g_git_curr_tag_name = 'unknown'

    d['__git_branch_name__'] = g_git_branch_name
    d['__git_last_update_time_std_fmt__'] = g_git_last_update_time_std_fmt
    d['__git_last_update_time_int_fmt__'] = g_git_last_update_time_int_fmt
    d['__git_int_version__'] = g_git_int_version
    d['__git_md5_version__'] = g_git_md5_version
    d['__g_git_last_update_message__'] = g_git_last_update_message
    d['__g_git_last_tag_name__'] = g_git_last_tag_name
    d['__g_git_curr_tag_name__'] = g_git_curr_tag_name

    return d


def lastindex(p_list=None, p_element=None):
    p_list.reverse()
    if p_element in p_list:
        index = len(p_list) - p_list.index(p_element) - 1
    else:
        index = 0
    return index


def get_git_info_branch_name():
    return get_git_info()['__git_branch_name__']


def get_git_info_last_update_time_std_fmt():
    return get_git_info()['__git_last_update_time_std_fmt__']


def get_git_info_last_update_time_int_fmt():
    return get_git_info()['__git_last_update_time_int_fmt__']


def get_git_info_int_version():
    return get_git_info()['__git_int_version__']


def get_git_info_md5_version():
    return get_git_info()['__git_md5_version__']


def get_git_last_update_message():
    return get_git_info()['__g_git_last_update_message__']


def get_git_last_tag_name():
    return get_git_info()['__g_git_last_tag_name__']


def get_git_curr_tag_name():
    return get_git_info()['__g_git_curr_tag_name__']


def is_windows():
    v = platform.system()
    return (v == 'Windows')


def get_os_name():
    """ get the os name, the value should one of 'Windows', 'Linux', 'Darwin'
    :return: version info
    :rtype: string
    """
    return platform.system()


def unicode2str(p_unicode=None):
    v = p_unicode.encode('unicode-escape').decode('string_escape') if p_unicode is not None else None
    return v


def str2unicode(p_str=None):
    v = p_str.decode('unicode-escape') if p_str is not None else None
    return v


def replaceregexp(p_target_file_name=None, p_matched_string=None, p_new_string=None, p_count=0):
    #
    output = []
    f = open(p_target_file_name)
    for i in f.readlines():
        if p_matched_string in i:
            output.append('\n%s\n' % (p_new_string))
        else:
            output.append(i)
    f.close()

    #
    with open(p_target_file_name, "r+") as f:
        f.seek(0)
        f.truncate()
    #
    with open(p_target_file_name, "r+") as f:
        for eachline in output:
            f.writelines(eachline)


def main(p_argv):
    kill_ngx_process_by()


def replace_text_in_file(p_target_file_path, p_matched_string, p_new_string):
    #
    print('replace_text_in_file')
    print(p_target_file_path)
    print(p_matched_string)
    print(p_new_string)

    f = open(p_target_file_path, 'r')
    alllines = f.readlines()
    f.close()
    #
    f = open(p_target_file_path, 'w+')
    for eachline in alllines:
        a = re.sub(p_matched_string, p_new_string, eachline)
        f.writelines(a)
    f.close()
    return 'replace_text_in_file ok'


def test():
    print('wukong test')


if __name__ == '__main__':
    sys.exit(main(sys.argv))
